#include "Dual_Link_List.h"

//Get the Node with specific index;
//Return: return the pointer to this node. If the index is illegal or the node cannot be found, NULL will be returned.
pNode getNode(pNode List, int index) {
	if((index<0) || (index>getLength(List)-1)) {
		printf("The index is illegal!\n");
		return NULL;
	}

	pNode p = List->next;
	if(p == List) {
		printf("This is the empty list, cannot get the node!\n");
		return NULL;
	}
	int count = 0;
	while((count < index) && (p != List)) {
		p = p->next;
		count++;
	}
	if(p != List)
		return p;
	else {
		printf("cannot find the node in this list\n");		
		return NULL;
	}
}

// Get the Node with specific index, 
// Return:If the element can be found, it will return SUCCESS, or it will return FAILURE.
Status getElement(pNode List, int index, BaseType* e) {
	pNode p = getNode(List,index);
	if(!p) {
		return FAILURE;
	}
	else {
		*e = p->data;
		return SUCCESS;
	}
}

// get the length of link list;
// Return: length of link list.
int getLength(pNode List) {
	pNode p = List->next;
	int length = 0;
	while(p != List){
		p = p->next;
		length++;
	}
	return length;
}

// insert a node with a given element into a link list before a specific location
// Return: return SUCEESS if success to insert node, or it will return FAILURE.
Status insertNode(pNode List, int location, BaseType data) {
	if((location < 0) || (location > getLength(List))) {
		printf("the laction is illegal!\n");
		return FAILURE;	
	}

	pNode p =(pNode)malloc(sizeof(LNode));
	if(!p)
		return FAILURE;
	p->data = data;
	p->next = NULL;
	p->prior = NULL;

	pNode q = NULL;
	if(location == getLength(List)) {
		q = List;
	}
	else {
		q = getNode(List,location);
		if(!q)
			return FAILURE;
	}
	q->prior->next = p;
	p->prior = q->prior;
	p->next = q;
	q->prior = p;

	return SUCCESS;
}

// delete a node from a link list with a specific location, the element of this deleted node will be return by para e.
// Return: return SUCCESS if delete successfully, or return FAILURE.
Status deleteNode(pNode List, int location, BaseType *e) {
	if((location < 0) || (location > getLength(List)-1))
		return FAILURE;		

	pNode p = getNode(List,location);

	*e = p->data;
	pNode q = p->next;
	p->prior->next = q;
	q->prior = p->prior;

	free(p);

	return SUCCESS;
}

// create a link list by reading data from a given file;
// Return the neck node of created list if success to create it, or NULL will be returned. 
pNode createLinkList(char* filename) {
	FILE* pFile;
	pFile = fopen(filename,"r");
	if(!pFile){
		//printf("fail to open file %c",filename);
		return NULL;
	}

	pNode L = (pNode)malloc(sizeof(LNode));
	if(!L) {
		printf("The neck node is allocated failure!");
		return NULL;
	}
	L->next = L;
	L->prior = L;

	char charReadFromFile;
	charReadFromFile = fgetc(pFile);
	while(charReadFromFile != EOF) {
		if(charReadFromFile == '\12') {
			charReadFromFile = fgetc(pFile);
			continue;
		}
		if(insertNode(L,getLength(L),charReadFromFile) == FAILURE) {
			printf("Fail to creat list.\n");
			return NULL;
		}
		charReadFromFile = fgetc(pFile);
	}
	return L;
}

// print the node of link list despite of its data type
// Return: void
void printNode(pNode p) {
	switch(BASETYPE) {
		case 0:printf("%c",p->data); break;
		case 1:printf("%d",p->data); break;
	}
}

// print all of nodes in link list sequencely to the screen
// Return: void
void printList(pNode List) {
	pNode p = List->next;
	if(p == List)
		printf("The List is empty!\n");
	else {
		printf("The List is: \n");
		while(p != List) {
			printNode(p);
			p = p->next;
		}
		printf("\n");
	}
}
